Skip to content

Unix: unmount all volumes when a new USB or Thunderbolt device is connected - #1984

Open
flatstik wants to merge 1 commit into
veracrypt:masterfrom
flatstik:fix-1982-unix-new-device
Open

flatstik wants to merge 1 commit into
veracrypt:masterfrom
flatstik:fix-1982-unix-new-device

Conversation

@flatstik

@flatstik flatstik commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Related to #1982 (the Windows part is #1983).

On Linux and macOS, VeraCrypt has no equivalent of "Clear encryption keys from memory if a new device is inserted". This PR adds one to Preferences > Security > Unmount All Volumes When: "A new USB or Thunderbolt device is connected".

  • Detecting devices. The GUI listens to kernel uevents on Linux (netlink, kernel messages only) and to IOKit first-match notifications on macOS. Devices connected when the option is enabled, or when VeraCrypt starts, are ignored. A device is identified by vendor, product and serial number, or by its port if it has no serial number.

  • On a new device. The password cache is wiped, then all volumes are unmounted even if files are open. A device connected while a wait dialog is open, or while volumes are being unmounted, is handled afterwards.

  • Linux: keys erased immediately. A forced unmount detaches the filesystem lazily, and the device-mapper devices are only removed once they are closed. So the keys would stay in memory while any file on the volume is open. This option therefore:

    • first replaces the table of the device-mapper devices of all volumes with an error target (DestroyVolumeKeys, dmsetup wipe_table --noflush --nolockfs), which frees the dm-crypt keys at once;
    • then cleans up each volume with EmergencyDismountVolume in a new destroyKeys mode, which aborts the volume's FUSE connection (/sys/fs/fuse/connections/<n>/abort, mounting fusectl there if needed) once its loop and device-mapper devices are released. The FUSE service then closes the volume, which erases its keys, and exits. --emergency-unmount is unchanged.

    Open files then fail with I/O errors, and their unsaved data is lost. The warning shown when the option is enabled says so.

  • macOS. A forced unmount (hdiutil detach -force) already releases the FUSE service. Discovery is the one the other automatic unmounts use, so a stalled FUSE-T mount blocks this too.

  • Linux preferences. Only this auto-unmount option is shown; the others stay hidden because unmounting may require the administrator password. If VeraCrypt has not obtained administrator privileges in the session, it asks for the password before unmounting, and the warning says so.

  • Lock. When the option is enabled, the user can also lock it. Until the session ends, the option cannot be disabled, the background task cannot be turned off, and VeraCrypt cannot be closed. The lock does not protect against someone who can run programs in the session, who can terminate VeraCrypt; the prompt says so.

Testing:

  • Tests/test_linux_new_device_unmount.py runs as root against the installed GUI under Xvfb. It refuses to run while other VeraCrypt volumes are mounted. It mounts a volume with kernel cryptography and one without, with a file open on each, and checks that:
    • a device connected before the GUI started does not unmount anything when the kernel reports it again;
    • a new USB device unmounts both volumes;
    • both open files then fail with EIO;
    • the device-mapper devices are removed or hold an error table;
    • no auxiliary mount remains and no VeraCrypt process still holds /dev/fuse.
  • The test is in build-linux.yml. It is skipped on the GitHub runners, whose Azure kernel has no dummy_hcd module.
  • I ran it in an Ubuntu 24.04 VM (kernel 6.8) with the GUI package built by this workflow, using QEMU's real USB hotplug (--connect-command). All checks pass. A second run with /sys/fs/fuse/connections unmounted passes too: VeraCrypt mounts fusectl itself.
  • The macOS code (NewDeviceMonitor.cpp and the changed GUI and Core files) only passed a clang++ -fsyntax-only check against Homebrew wxWidgets on a macOS runner. I do not have a Mac, so it is neither linked nor run-tested.

Known limits:

  • A device is recognized by what it reports (vendor, product, serial number) or by its port. A device that imitates one connected at start is not detected; the Windows option has the same limit.
  • FireWire and PCI hotplug are not watched.
  • If hotplug events are lost (ENOBUFS), connected devices are compared with those known at start, so a device connected and removed again meanwhile is missed. Treating the loss as a trigger would let a udevadm trigger burst unmount every volume.
  • A FUSE worker blocked on backing-file I/O keeps its keys until that I/O returns.
  • The test runs the GUI as root, so the path through the elevated service of a non-root GUI is not covered by it.
  • A lock does not survive VeraCrypt being terminated.

Since I cannot test on Windows or macOS, please feel free to merge this, close it, or take it as a basis for your own implementation, as you see fit. I will adjust the Linux/Unix part according to your suggestions.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical flaws can prevent emergency unmounting and leave volume keys or cached passwords in memory when monitoring, discovery, or cleanup fails.

15 open issues
What changed in this PR

This PR adds device-insertion protection to VeraCrypt’s Linux and macOS GUI, complementing the Windows work in #1983 and the locking request in #1982.

Changes:

  • Adds USB and Thunderbolt monitoring, forced automatic unmounting, and an optional session lock.
  • Extends Linux emergency teardown to wipe device-mapper tables and abort FUSE connections.
  • Adds security messages and a Linux hotplug integration test with workflow integration.
File Description
Translations/​Language.zh-tw.xml Adds English fallback security messages.
Translations/​Language.zh-hk.xml Adds English fallback security messages.
Translations/​Language.zh-cn.xml Adds English fallback security messages.
Translations/​Language.vi.xml Adds English fallback security messages.
Translations/​Language.uz.xml Adds English fallback security messages.
Translations/​Language.uk.xml Adds English fallback security messages.
Translations/​Language.tr.xml Adds English fallback security messages.
Translations/​Language.th.xml Adds English fallback security messages.
Translations/​Language.sv.xml Adds English fallback security messages.
Translations/​Language.sl.xml Adds English fallback security messages.
Translations/​Language.sk.xml Adds English fallback security messages.
Translations/​Language.ru.xml Adds English fallback security messages.
Translations/​Language.ro.xml Adds English fallback security messages.
Translations/​Language.pt-br.xml Adds English fallback security messages.
Translations/​Language.pl.xml Adds English fallback security messages.
Translations/​Language.nn.xml Adds English fallback security messages.
Translations/​Language.nl.xml Adds English fallback security messages.
Translations/​Language.nb.xml Adds English fallback security messages.
Translations/​Language.my.xml Adds English fallback security messages.
Translations/​Language.lv.xml Adds English fallback security messages.
Translations/​Language.ko.xml Adds English fallback security messages.
Translations/​Language.ka.xml Adds English fallback security messages.
Translations/​Language.ja.xml Adds English fallback security messages.
Translations/​Language.it.xml Adds English fallback security messages.
Translations/​Language.id.xml Adds English fallback security messages.
Translations/​Language.hu.xml Adds English fallback security messages.
Translations/​Language.he.xml Adds English fallback security messages.
Translations/​Language.fr.xml Adds English fallback security messages.
Translations/​Language.fi.xml Adds English fallback security messages.
Translations/​Language.fa.xml Adds English fallback security messages.
Translations/​Language.eu.xml Adds English fallback security messages.
Translations/​Language.et.xml Adds English fallback security messages.
Translations/​Language.es.xml Adds English fallback security messages.
Translations/​Language.el.xml Adds English fallback security messages.
Translations/​Language.de.xml Adds English fallback security messages.
Translations/​Language.da.xml Adds English fallback security messages.
Translations/​Language.cs.xml Adds English fallback security messages.
Translations/​Language.co.xml Adds English fallback security messages.
Translations/​Language.ca.xml Adds English fallback security messages.
Translations/​Language.bg.xml Adds English fallback security messages.
Translations/​Language.be.xml Adds English fallback security messages.
Translations/​Language.ar.xml Adds English fallback security messages.
Tests/​test_linux_new_device_unmount.py Tests hotplug unmounting and key-erasure behavior.
src/​Main/​UserPreferences.h Defines the new preference and its default.
src/​Main/​UserPreferences.cpp Loads and saves the new preference.
src/​Main/​NewDeviceMonitor.h Declares the device-monitor interface.
src/​Main/​NewDeviceMonitor.cpp Implements Linux and macOS device monitoring.
src/​Main/​Main.make Includes the monitor in GUI builds.
src/​Main/​GraphicUserInterface.h Declares monitoring, pending-event, and lock state.
src/​Main/​GraphicUserInterface.cpp Handles insertion-triggered unmounting and cache clearing.
src/​Main/​Forms/​TrueCrypt.fbp Adds the security checkbox to the form definition.
src/​Main/​Forms/​PreferencesDialog.h Declares the checkbox handler and lock selection.
src/​Main/​Forms/​PreferencesDialog.cpp Applies the preference, warnings, and session lock.
src/​Main/​Forms/​MainFrame.h Adds the locked-exit guard.
src/​Main/​Forms/​MainFrame.cpp Starts monitoring, processes pending events, and guards exit.
src/​Main/​Forms/​Forms.h Declares the generated checkbox and event handler.
src/​Main/​Forms/​Forms.cpp Creates and wires the generated checkbox.
src/​Core/​Unix/​Linux/​CoreLinux.h Declares Linux key-destruction and service-abort hooks.
src/​Core/​Unix/​Linux/​CoreLinux.cpp Implements mapper-table wiping and FUSE connection aborts.
src/​Core/​Unix/​CoreUnix.h Extends the emergency-unmount interface.
src/​Core/​Unix/​CoreUnix.cpp Coordinates key destruction during emergency teardown.
src/​Core/​Unix/​CoreServiceRequest.h Adds the key-destruction request flag.
src/​Core/​Unix/​CoreServiceRequest.cpp Serializes the key-destruction request flag.
src/​Core/​Unix/​CoreServiceProxy.h Forwards the emergency-unmount mode.
src/​Core/​Unix/​CoreService.h Extends the service request interface.
src/​Core/​Unix/​CoreService.cpp Dispatches and forwards the key-destruction mode.
src/​Core/​CoreBase.h Extends the shared emergency-unmount API.
src/​Common/​Language.xml Defines device-unmount warnings and lock messages.
.github/​workflows/​build-linux.yml Adds the hotplug test and its prerequisites.

Review effort: Max

Comment thread Tests/test_linux_new_device_unmount.py Resolved
Comment thread src/Core/Unix/Linux/CoreLinux.cpp Resolved
Comment thread src/Main/Forms/PreferencesDialog.cpp Resolved
Comment thread src/Main/GraphicUserInterface.cpp Resolved
Comment thread src/Main/GraphicUserInterface.cpp Resolved
Comment thread src/Main/NewDeviceMonitor.cpp Resolved
Comment thread src/Main/NewDeviceMonitor.cpp Resolved
Comment thread src/Core/Unix/Linux/CoreLinux.cpp Resolved
Comment thread src/Main/Forms/PreferencesDialog.cpp Resolved
Comment thread src/Main/GraphicUserInterface.cpp Resolved
…nected

On Windows, "Clear encryption keys from memory if a new device is
inserted" protects an unlocked machine against devices connected to
extract its memory (veracrypt#1982). Linux and macOS have no equivalent.

Add "A new USB or Thunderbolt device is connected" to Preferences >
Security > Unmount All Volumes When. The GUI listens to kernel uevents
on Linux and to IOKit notifications on macOS. Devices connected when
the option is enabled or VeraCrypt starts are ignored; a device is
identified by its vendor, product and serial number, or by its port
without a serial number. On a new device, all volumes are unmounted
even if files are open, and the password cache is wiped.

On Linux, a forced unmount detaches the filesystem lazily and removes
the device-mapper devices when they are closed, so the keys would
stay in memory while a file is open. DestroyVolumeKeys replaces the
table of a volume's device-mapper devices with an error target, for
all volumes before the cleanup of any. EmergencyDismountVolume can then
also abort the FUSE connection, once the volume's loop and device-mapper
devices are released, so that the FUSE service closes the volume, which
erases its keys, and exits. Open files then fail with I/O errors. The
CLI's --emergency-unmount is unchanged.

When the option is enabled, the user can also lock it: the option
then cannot be disabled, and VeraCrypt cannot be closed, until the
session ends. On Linux, only this auto-unmount option is shown, as
unmounting may require the administrator password.

Tests/test_linux_new_device_unmount.py checks it against the installed
GUI. It is skipped without the dummy_hcd module, as on the GitHub
runners, unless --connect-command connects a new device.

Related to veracrypt#1982
@flatstik
flatstik force-pushed the fix-1982-unix-new-device branch from 8d75f16 to d279fa5 Compare November 7, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants